﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace EventLogAdmin
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private string machineName = ".";

        #region Form events
        private void FormMain_Load(object sender, EventArgs e)
        {
            ResizeListViews();
        }
        private void FormMain_Shown(object sender, EventArgs e)
        {
            LoadEventLogs();
        }
        private void FormMain_Resize(object sender, EventArgs e)
        {
            ResizeListViews();
        }
        private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
        {
            ResizeListViews();
        }
        #endregion

        #region Event log list view events
        private void lvwLogs_SelectedIndexChanged(object sender, EventArgs e)
        {
            CheckLogMenuItemsEnabled();
            LoadEventSources();
            DisplayStatusses();
        }
        #endregion

        #region Event source list view events
        private void lvwSources_SelectedIndexChanged(object sender, EventArgs e)
        {
            CheckSourceMenuItemsEnabled();
            DisplayStatusses();
        }
        #endregion

        #region Private methods
        private void ResizeListViews()
        {
            columnHeaderLogs.Width = lvwLogs.ClientSize.Width;
            columnHeaderSource.Width = lvwSources.ClientSize.Width;
        }
        private void LoadEventLogs()
        {
            try
            {
                Text = string.Format("Event log admin - {0}", machineName);
                lvwLogs.BeginUpdate();
                lvwLogs.Items.Clear();
                lvwSources.Items.Clear();
                EventLog[] logs = EventLog.GetEventLogs(machineName);
                foreach (EventLog log in (from EventLog l in logs
                                          where !Properties.Settings.Default.HiddenLogs.Contains(l.LogDisplayName)
                                          orderby l.LogDisplayName
                                          select l))
                {
                    ListViewItem lvi = new ListViewItem(log.LogDisplayName);
                    lvi.Tag = log;
                    lvwLogs.Items.Add(lvi);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                lvwLogs.EndUpdate();
            }
        }
        private void CheckLogMenuItemsEnabled()
        {
            if (Properties.Settings.Default.ReservedLogs == null)
                Properties.Settings.Default.ReservedLogs = new System.Collections.Specialized.StringCollection();

            bool reservedLogSelected = false;
            foreach (EventLog log in (from ListViewItem l in lvwLogs.SelectedItems
                                      select (EventLog)l.Tag))
            {
                if (Properties.Settings.Default.ReservedLogs.Contains(log.LogDisplayName))
                {
                    reservedLogSelected = true;
                    break;
                }
            }
            deleteLogToolStripMenuItem.Enabled = (!reservedLogSelected) && lvwLogs.SelectedItems.Count > 0;
            deleteLogToolStripMenuItem1.Enabled = (!reservedLogSelected) && lvwLogs.SelectedItems.Count > 0;
            propertiesToolStripMenuItem.Enabled = lvwLogs.SelectedItems.Count > 0;
            propertiesToolStripMenuItem1.Enabled = lvwLogs.SelectedItems.Count > 0;
            createSourceToolStripMenuItem.Enabled = lvwLogs.SelectedItems.Count > 0;
            createSourceToolStripMenuItem1.Enabled = lvwLogs.SelectedItems.Count > 0;
            findAllinCurrentSelectedLogToolStripMenuItem.Enabled = lvwLogs.SelectedItems.Count > 0;
        }
        private void CheckSourceMenuItemsEnabled()
        {
            bool defaultSourceSelected = false;
            if (lvwLogs.SelectedItems.Count > 0 && lvwSources.SelectedItems.Count > 0)
            {
                if ((from ListViewItem lvi in lvwSources.SelectedItems
                     where lvi.Text == lvwLogs.SelectedItems[0].Text
                     select lvi).Count() > 0)
                    defaultSourceSelected = true;
            }
            deleteSourceToolStripMenuItem.Enabled = lvwLogs.SelectedItems.Count > 0 && lvwSources.SelectedItems.Count > 0 && !defaultSourceSelected;
            deleteSourceToolStripMenuItem1.Enabled = lvwLogs.SelectedItems.Count > 0 && lvwSources.SelectedItems.Count > 0 && !defaultSourceSelected;
        }
        private void LoadEventSources()
        {
            try
            {
                lvwSources.BeginUpdate();
                lvwSources.Items.Clear();
                if (lvwLogs.SelectedItems.Count > 0)
                {                    
                    EventLog evl = (EventLog)lvwLogs.SelectedItems[0].Tag;
                    foreach (string source in EventLogUtil.GetEventSources(machineName, evl.LogDisplayName))
                    {
                        lvwSources.Items.Add(source);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                lvwSources.EndUpdate();
            }
        }
        private void DisplayStatusses()
        {
            StringBuilder status = new StringBuilder();
            status.Append(string.Format("{0} Event log(s)", lvwLogs.Items.Count));
            if (lvwLogs.SelectedItems.Count > 0)
            {
                status.Append(string.Format(", {0} selected", lvwLogs.SelectedItems.Count));
                status.Append(string.Format(", {0} source(s)", lvwSources.Items.Count));
                if (lvwSources.SelectedItems.Count > 0)
                {
                    status.Append(string.Format(", {0} selected", lvwSources.SelectedItems.Count));
                }
            }
            toolStripStatusLabelSelections.Text = status.ToString();
        } 
        #endregion

        #region Event Log menu events
        private void createLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EventLogEdit eventLogEdit = new EventLogEdit();
            if (eventLogEdit.AddEventlog(machineName) == System.Windows.Forms.DialogResult.OK)
            {
                LoadEventLogs();
            }
        }
        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwLogs.SelectedItems.Count > 0)
            {
                EventLogEdit eventLogEdit = new EventLogEdit();
                eventLogEdit.EditEventLog(machineName, lvwLogs.SelectedItems[0].Text);
            }
        }
        private void deleteLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwLogs.SelectedItems.Count > 0 && MessageBox.Show("Are you really sure you want to delete the selected Event Log(s)?\r\nThis cannot be undone", "Delete Event Log", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                foreach (ListViewItem lvi in lvwLogs.SelectedItems)
                {
                    try
                    {
                        EventLog.Delete(lvi.Text, machineName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                LoadEventLogs();
                CheckLogMenuItemsEnabled();
            }
        } 
        #endregion

        #region Event Source menu events
        private void createSourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwLogs.SelectedItems.Count > 0) // && lvwLogs.SelectedItems[0].Text != "Security")
            {
                AddEventSourceForm addEventSourceForm = new AddEventSourceForm();
                if (addEventSourceForm.AddSource(machineName, lvwLogs.SelectedItems[0].Text) == System.Windows.Forms.DialogResult.OK)
                {
                    LoadEventSources();
                }
            }
        }
        private void deleteSourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwLogs.SelectedItems.Count > 0 && MessageBox.Show("Are you sure you want to delete this Event source(s)?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                foreach (ListViewItem lvi in lvwSources.SelectedItems)
                {
                    try
                    {
                        if (lvi.Text != lvwLogs.SelectedItems[0].Text)
                        {
                            EventLog.DeleteEventSource(lvi.Text, machineName);
                            if (lvwLogs.SelectedItems[0].Text != "Security" && (machineName == "." || System.Net.Dns.GetHostName().ToUpper() == machineName.ToUpper()))
                                EventLog.WriteEntry(lvwLogs.SelectedItems[0].Text, string.Format("Event source {0} deleted", lvi.Text));
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Delete", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                LoadEventSources();
            }
        } 
        #endregion

        #region Toolbar menu Find events
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            InputBox inputBox = new InputBox();
            inputBox.Text = "Find Event Source";
            inputBox.Prompt = "Event source to find: (text must match exactly)";
            if (inputBox.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (inputBox.SelectedText.Length > 0 && EventLog.SourceExists(inputBox.SelectedText, machineName))
                {
                    string logName = EventLog.LogNameFromSourceName(inputBox.SelectedText, machineName);
                    lvwLogs.SelectedItems.Clear();
                    ListViewItem lviLog = (from ListViewItem lvi in lvwLogs.Items
                                           where lvi.Text == logName
                                           select lvi).First();
                    lviLog.Selected = true;
                    lviLog.EnsureVisible();
                    lvwSources.SelectedItems.Clear();
                    ListViewItem lviSource = (from ListViewItem lvi in lvwSources.Items
                                              where lvi.Text == inputBox.SelectedText
                                              select lvi).First();
                    lviSource.Selected = true;
                    lviSource.EnsureVisible();
                    lvwSources.Focus();

                }
                else if (inputBox.SelectedText.Length > 0)
                {
                    MessageBox.Show("Event source does not exist!", "Find event source", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }
        private void findAllinCurrentSelectedLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InputBox inputBox = new InputBox();
            inputBox.Text = "Find Event Sources";
            inputBox.Prompt = "Specify criteria to find Event source(s)";
            if (inputBox.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (inputBox.SelectedText.Length > 0)
                {
                    lvwSources.SelectedItems.Clear();
                    foreach (ListViewItem lvi in (from ListViewItem l in lvwSources.Items
                                                  where l.Text.ToUpper().Contains(inputBox.SelectedText.ToUpper())
                                                  select l))
                    {
                        lvi.Selected = true;
                    }
                    lvwSources.Focus();
                    if (lvwSources.SelectedItems.Count > 0)
                        lvwSources.SelectedItems[0].EnsureVisible();
                    else
                        MessageBox.Show("No Event sources found that match the search criteria!", "Find event source", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        } 
        #endregion

        #region Toolbar machine button
        private void toolStripButtonMachine_Click(object sender, EventArgs e)
        {
            InputBox inputBox = new InputBox();
            inputBox.Text = "Connect to machine";
            inputBox.Prompt = "Specify computer name to connect to (use . for local machine)";
            inputBox.SelectedText = machineName;
            if (inputBox.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    if (inputBox.SelectedText.Length > 0)
                    {
                        if (inputBox.SelectedText == "." || System.Net.Dns.GetHostEntry(inputBox.SelectedText).AddressList.Count() > 0)
                            machineName = inputBox.SelectedText;
                        LoadEventLogs();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Specified computer name may be invalid or machine not accessible!\r\nError details: {0}", ex.Message), "Connect", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        } 
        #endregion

        private void toolStripButtonAbout_Click(object sender, EventArgs e)
        {
            string aboutDetails = string.Format("Application name: {0}\r\nVersion: {1}\r\nCreated by: {2}", 
                Application.ProductName,
                Application.ProductVersion,
                Application.CompanyName);
            MessageBox.Show(aboutDetails, "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

    }
}
